package com.xiguaji.tiktok.task.blogger;

import com.gugee.tiktok.common.model.mysql.BloggerLog;
import com.xiguaji.boot.eventbus.EventBusTemplate;
import com.xiguaji.boot.toolkit.JsonUtil;
import com.xiguaji.tiktok.task.blogger.event.*;
import com.xiguaji.tiktok.task.common.job.JobParam;
import com.xiguaji.tiktok.task.common.job.TaskParam;
import com.xiguaji.tiktok.task.core.ScheduleTemplate;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Slf4j

public class BloggerTask {

    @Lazy
    @Autowired
    EventBusTemplate eventBusTemplate;

    @Autowired
    ScheduleTemplate scheduleTemplate;

    @Autowired
    BloggerService bloggerService;
    @Autowired
    MarkerBloggerService markerBloggerService;
    /**
     * 获取新用户关注列表
     *
     * @param param
     * @return
     */
    @XxlJob("fetchFollowingHandler")
    public ReturnT<String> fetchFollowingHandler(String param) {
        var fetchNewFollowingEvent = new FetchFollowingEventListener.FetchFollowingEvent(false);
        scheduleTemplate.run("FetchFollowingHandlerPool", 5, 5000, () -> eventBusTemplate.post(fetchNewFollowingEvent));
        return ReturnT.SUCCESS;
    }

    /**
     * 循环获取用户关注列表
     *
     * @param param
     * @return
     */
    @XxlJob("fetchFollowingLoopHandler")
    public ReturnT<String> fetchFollowingLoopHandler(String param) {
        var fetchNewFollowingEvent = new FetchFollowingEventListener.FetchFollowingEvent(true);
        scheduleTemplate.run("FetchFollowingLoopHandlerPool", 5, 5000, () -> eventBusTemplate.post(fetchNewFollowingEvent));
        return ReturnT.SUCCESS;
    }

    /**
     * 获取新用户粉丝列表
     *
     * @param param
     * @return
     */
    @XxlJob("fetchFollowerHandler")
    public ReturnT<String> fetchFollowerHandler(String param) {
        var fetchNewFollowerEvent = new FetchFollowerEventListener.FetchFollowerEvent(false);
        scheduleTemplate.run("FetchFollowerHandler", 5, 5000,
                () -> eventBusTemplate.post(fetchNewFollowerEvent));
        return ReturnT.SUCCESS;
    }

    /**
     * 循环获取用户粉丝列表
     */
    @XxlJob("fetchFollowerLoopHandler")
    public ReturnT<String> fetchFollowerLoopHandler(String param) {
        var fetchNewFollowerEvent = new FetchFollowerEventListener.FetchFollowerEvent(true);
        scheduleTemplate.run("FetchFollowerLoopHandlerPool", 5, 5000,
                () -> eventBusTemplate.post(fetchNewFollowerEvent));
        return ReturnT.SUCCESS;
    }

    /**
     * 循环更新BloggerMain用户信息,并获取或者更新视频数据  每2分钟一次
     * RefreshBloggerMainEventListener==>>UpdateBloggerMainEventListener==>>
     * RefreshBloggerMainEventListener:
     *      从blogger_main表获取2000名播主
     * UpdateBloggerMainEventListener：
     *      爬取指定播主信息
     *      awemeClient.refreshBloggerAweme(uid)：
     *           SaveBloggerAwemeEventListener
     *           爬取播主的视频列表，将90天内的新视频入库，顺带保存、更新视频图片到S3
     * awemeClient.refreshBloggerAwemeScore：
     *      计算并更新播主90天内视频分数
     * awemeClient.refreshBloggerAwemeForES(blogger.getOUid())：
     *      保存到ES，逻辑较复杂，请看代码
     * 计算博主得分，并更新到BloggerMain表
     * ESSaveBloggerMainEventListener：
     *      保存播主到ES
     */
    @XxlJob("refreshBloggerMainLoopHandler")
//    @RedisMonitor
    public ReturnT<String> refreshBloggerMainLoopHandler(String param) {
        try {
            long start = System.currentTimeMillis();
            XxlJobLogger.log("更新BloggerMain用户及视频: params={}", param);
            log.info("更新BloggerMain用户及视频: params={}", param);
            JobParam jobParam= JsonUtil.jsonParse(JobParam.class,param);

            var refreshBloggerEvent = new RefreshBloggerMainEventListener.RefreshBloggerMainEvent(jobParam);
            //scheduleTemplate.run("RefreshBloggerMainLoopHandlerPool", 10, 3000, () -> eventBusTemplate.post(refreshBloggerEvent));
            eventBusTemplate.post(refreshBloggerEvent);
            XxlJobLogger.log("更新BloggerMain用户及视频  end cost total={},", (System.currentTimeMillis() - start) / 1000);
            log.info("更新BloggerMain用户及视频  end cost total={},avgTimes={}", (System.currentTimeMillis() - start) / 1000,(System.currentTimeMillis() - start) / (1000*jobParam.getCollectLimitCounts()));
        }catch (Exception ex) {
            XxlJobLogger.log(ex);
            log.info("任务发生异常{}",ex);
        }

        return ReturnT.SUCCESS;
    }

    /**
     * 播主投递
     * @param param
     * @return
     */
    @XxlJob("sendBlogger2kafkaHandler")
    public ReturnT<String> sendBlogger2kafkaHandler(String param) {
        long start = System.currentTimeMillis();
        try {
            XxlJobLogger.log("开始启动播主投递任务: params={}", param);
            TaskParam taskParam = JsonUtil.jsonParse(TaskParam.class, param);
             if(taskParam==null){
                 XxlJobLogger.log("json解析失败："+param);
                 return ReturnT.FAIL;
             }

             int bloggerLogType = BloggerLog.BloggerLogType.REFRESH_BLOGGER_MAIN_LOOP.getValue();
             if(taskParam.getTopic().equals("blogger_fans_portrait")){ //粉丝画像计算队列
                 bloggerLogType = BloggerLog.BloggerLogType.REFRESH_BLOGGER_FANS_PORTRAIT_LOOP.getValue();
             }
            bloggerService.sendMsg2Kafka(bloggerLogType,"sendBlogger2kafkaHandler",taskParam);
            return ReturnT.SUCCESS;
        } catch (Exception ex) {
            XxlJobLogger.log(ex);
            return ReturnT.FAIL;
        }finally {
            XxlJobLogger.log("投递结束  end cost total={},", (System.currentTimeMillis() - start) / 1000);
        }
    }

    /**
     * 排行版播主投递
     * @param param
     * @return
     */
    @XxlJob("sendRankingBlogger2kafkaHandler")
    public ReturnT<String> sendRankingBlogger2kafkaHandler(String param) {
        long start = System.currentTimeMillis();
        try {
            XxlJobLogger.log("开始启动排行版播主投递任务: params={}", param);
            TaskParam taskParam = JsonUtil.jsonParse(TaskParam.class, param);
            bloggerService.sendMsgWithAllTypes(taskParam);
            return ReturnT.SUCCESS;
        } catch (Exception ex) {
            XxlJobLogger.log(ex);
            return ReturnT.FAIL;
        }finally {
            XxlJobLogger.log("投递结束  end cost total={},", (System.currentTimeMillis() - start) / 1000);
        }
    }
    /**
     * 星图中的播主投递
     * @param param
     * @return
     */
    @XxlJob("sendMarkerBlogger2kafkaHandler")
    public ReturnT<String> sendMarkerBlogger2kafkaHandler(String param) {
        return markerBloggerService.xxlJobStart(BloggerLog.BloggerLogType.SEND_MARKER_BLOGGER_2_KAFKA,"sendMarkerBlogger2kafkaHandler",param,false);
    }


    /**
     * 更新榜单前1000的博主信息
     * @param param
     * @return
     */
//    @XxlJob("refreshTopBloggerMainHandler")
////    @RedisMonitor
//    public ReturnT<String> refreshTopBloggerMainHandler(String param) {
//        try {
//            System.out.println(Thread.currentThread().getName());
//            long start = System.currentTimeMillis();
//            XxlJobLogger.log("更新榜单前1000用户及视频:params={}", param);
//            var refreshTopBloggerEvent = new RefreshTopBloggerMainEventListener.RefreshTopBloggerMainEvent();
//            //scheduleTemplate.run("RefreshBloggerMainLoopHandlerPool", 10, 3000, () -> eventBusTemplate.post(refreshBloggerEvent));
//            eventBusTemplate.post(refreshTopBloggerEvent);
//            XxlJobLogger.log("更新榜单前1000用户及视频  end cost total={},", (System.currentTimeMillis() - start) / 1000);
//            log.info("更新榜单前1000用户及视频  end cost total={},", (System.currentTimeMillis() - start) / 1000);
//        }catch (Exception ex) {
//            XxlJobLogger.log(ex);
//            log.info("任务发生异常{}",ex);
//        }
//
//        return ReturnT.SUCCESS;
//    }


    /**
     * 更新Tiktok监控的播主（My Tiktok）
     * @param param
     * @return
     */
    @XxlJob("monitorBloggerMainHandler")
    public ReturnT<String> monitorBloggerMainHandler(String param){
        val monitorBloggerMainEvent = new MonitorBloggerMainEventListener.MonitorBloggerMainEvent();
        eventBusTemplate.post(monitorBloggerMainEvent);

        return ReturnT.SUCCESS;
    }

    /**
     * 指定播主unique_id列表
     * @param param
     * @return
     */
//    @XxlJob("refreshCustomBloggerMainHandler")
//    public ReturnT<String> refreshCustomBloggerMainHandler(String param) {
//        try {
//            System.out.println(Thread.currentThread().getName());
//            long start = System.currentTimeMillis();
//            XxlJobLogger.log("指定播主更新:params={}", param);
//            var refreshCustomBloggerEvent = new RefreshCustomBloggerMainEventListener.RefreshCustomBloggerMainEvent(param);
//            eventBusTemplate.post(refreshCustomBloggerEvent);
//            XxlJobLogger.log("指定播主更新  end cost total={},", (System.currentTimeMillis() - start) / 1000);
//            log.info("指定播主更新  end cost total={},", (System.currentTimeMillis() - start) / 1000);
//        }catch (Exception ex) {
//            XxlJobLogger.log(ex);
//            log.info("任务发生异常{}",ex);
//        }
//
//        return ReturnT.SUCCESS;
//    }
    /**
     * 循环更新Blogger用户信息 每分钟一次
     * RefreshBloggerEventListener==>>SaveBloggerEventListener
     *
     */
    @XxlJob("refreshBloggerLoopHandler")
    public ReturnT<String> refreshBloggerLoopHandler(String param) {
        var refreshBloggerEvent = new RefreshBloggerEventListener.RefreshBloggerEvent();
        //scheduleTemplate.run("RefreshBloggerLoopHandlerPool", 5, 3000, () -> eventBusTemplate.post(refreshBloggerEvent));
        eventBusTemplate.post(refreshBloggerEvent);
        return ReturnT.SUCCESS;
    }

    /**
     * 收录万粉以上播主至blogger_main
     * @param param
     * @return
     */
    @XxlJob("fetchBloggerMainLoopHandler")
    public ReturnT<String> fetchBloggerMainLoopHandler(String param) {
        long start = System.currentTimeMillis();
        try {
            log.info("开始收录万粉以上播主至blogger_main任务: params={}", param);
            XxlJobLogger.log("开始收录万粉以上播主至blogger_main任务: params={}", param);
            TaskParam jobParam = JsonUtil.jsonParse(TaskParam.class, param);
            int bloggerLogType = BloggerLog.BloggerLogType.FETCH_BLOGGER_MAIN.getValue();
            bloggerService.collectBloggerMainFromBlogger(bloggerLogType,"fetchBloggerMainLoopHandler",jobParam);
            return ReturnT.SUCCESS;
        } catch (Exception ex) {
            XxlJobLogger.log(ex);
            log.error(ex.getMessage());
            return ReturnT.FAIL;
        }finally {
            log.info("结束  end cost total={},", (System.currentTimeMillis() - start) / 1000);
            XxlJobLogger.log("结束  end cost total={}, params={}", (System.currentTimeMillis() - start) / 1000,param);
        }
    }
    /**
     * 记录每天的博主信息 每隔两分钟一次
     * ==》》ESSaveBloggerMainEventListener
     * @param params
     * @return
     */
    @XxlJob("refreshBloggerRecordEventListener")
    public ReturnT<String> refreshBloggerRecordEventListener(String params) {
        val refreshBloggerRecordEvent = new RefreshBloggerRecordEventListener.RefreshBloggerRecordEvent();
        eventBusTemplate.post(refreshBloggerRecordEvent);
        return ReturnT.SUCCESS;
    }


    /**
     * 博主及作品分类  50分钟一次
     * @param params
     * @return
     */
    @XxlJob("refreshBloggerMainCategoriesEventListener")
    public ReturnT<String> refreshBloggerMainCategoriesEventListener(String params) {

        try {
            System.out.println(Thread.currentThread().getName());
            long start = System.currentTimeMillis();
            TaskParam taskParam= JsonUtil.jsonParse(TaskParam.class,params);
            XxlJobLogger.log("博主及作品分类:params={}", params);
            val refreshBloggerMainCategoriesEvent = new RefreshBloggerMainCategoriesEventListener.RefreshBloggerMainCategoriesEvent(taskParam);
            //scheduleTemplate.run("RefreshBloggerMainLoopHandlerPool", 10, 3000, () -> eventBusTemplate.post(refreshBloggerMainCategoriesEvent));
            eventBusTemplate.post(refreshBloggerMainCategoriesEvent);
            XxlJobLogger.log("博主及作品分类  end cost total={}s,", (System.currentTimeMillis() - start) / 1000);
        }catch (Exception ex) {
            XxlJobLogger.log(ex);
            log.info("任务发生异常{}",ex);
        }

        return ReturnT.SUCCESS;
    }




//    /**
//     * 更新数据到es
//     * @param param
//     * @return
//     */
//    @XxlJob("esRefreshBloggerMainHandler")
//    public ReturnT<String> esRefreshBloggerMainHandler(String param) {
//        val esRefreshBloggerMainEvent = new ESRefreshBloggerMainEventListener.ESRefreshBloggerMainEvent();
//        eventBusTemplate.post(esRefreshBloggerMainEvent);
//        return ReturnT.SUCCESS;
//    }

//    @XxlJob("RefreshAuditBloggerMainHandler")
//    public ReturnT<String> fetchAuditBlogger(String param) {
//        var event = new RefreshAuditBloggerMainEventListener.RefreshAuditBloggerMainEvent();
//        eventBusTemplate.post(event);
//        return ReturnT.SUCCESS;
//    }
}
